local snow    = require("meet_your_mods.mhr").snow
local status  = require("meet_your_mods.status")
local routine = require("meet_your_mods.routine_framework")
local setting = require("meet_your_mods.setting")
local ui      = require("meet_your_mods.ui")

snow.enemy.EnemyManager:fetch_method("find_boss_init_position",
    "findBossInitPosition(System.Int32, System.Int32, snow.QuestMapManager.MapNoType, System.Boolean)")

local no_random = {
    setting = {
        spawn_area     = 4,
        spawn_position = 4,
        fixed_scale    = false,
        scale          = 1.0,
    },

    config = nil,
}

--在给定尺寸列表中查找最接近给定尺寸的元素
function no_random.search_target_scale(scale_list, scale)
    local left   = 1
    local right  = #scale_list
    local target = 0

    while left < right do
        target = (left + right) >> 1
        if math.abs(scale - scale_list[target]._Scale) < 1e-6 then
            return target
        elseif scale > scale_list[target]._Scale then
            left = target + 1
        else
            right = target
        end
    end

    if left ~= 1 and math.abs(scale - scale_list[left]._Scale) > math.abs(scale - scale_list[left - 1]._Scale) then
        return left - 1
    end
    return left
end

--开关固定尺寸
function no_random:toggle_fixed_scale()
    if self.setting.fixed_scale then
        self:change_scale_rate()
    else
        self:reset_scale_rate()
    end
end

--变更尺寸概率
function no_random:change_scale_rate()
    if not self.config then
        return
    end

    for _, scale_list in pairs(snow.enemy.EnemyManager:get_singleton():getBossRandomScale()._RandomScaleTableDataList) do
        for _, data in pairs(scale_list._ScaleAndRateData) do
            data._Rate = 0
        end

        --查找最接近给定尺寸的尺寸
        local target = self.search_target_scale(scale_list._ScaleAndRateData, self.setting.scale)
        scale_list._ScaleAndRateData[target]._Rate = 100
    end
end

--还原尺寸概率
function no_random:reset_scale_rate()
    if not self.config then
        return
    end

    for list_index, scale_list in pairs(snow.enemy.EnemyManager:get_singleton():getBossRandomScale()._RandomScaleTableDataList) do
        for data_index, data in pairs(scale_list._ScaleAndRateData) do
            data._Rate = self.config[list_index][data_index]
        end
    end
end

function no_random:change_spawn_area(result)
    local map = status:current_map()
    if snow.QuestMapManager.MapNoType.yawning_abyss == map
        or snow.QuestMapManager.MapNoType.forlorn_arena == map
        or snow.QuestMapManager.MapNoType.coral_palace == map
        or snow.QuestMapManager.MapNoType.arena == map
        or snow.QuestMapManager.MapNoType.infernal_springs == map
    then
        return result
    end

    local set_data = sdk.to_managed_object(result)
    if set_data._SetName ~= "メイン" and set_data._SetName ~= "メイン2" then
        return result
    end

    for index, info in pairs({ 60, 30, 10, }) do
        if self.setting.spawn_area < 4 then
            set_data.Info[index] = index == self.setting.spawn_area and 100 or 0
        else
            set_data.Info[index] = info
        end
    end

    return result
end

--读取怪物尺寸概率配置
function no_random:load_config()
    local config = {}
    for _, scale_list in pairs(snow.enemy.EnemyManager:get_singleton():getBossRandomScale()._RandomScaleTableDataList) do
        local rate_list  = {}
        for _, data in pairs(scale_list._ScaleAndRateData) do
            table.insert(rate_list, data._Rate)
        end
        table.insert(config, rate_list)
    end

    return config
end

function no_random:post_before_village()
    if self.config then
        return
    end
    self.config = self:load_config()

    if self.setting.fixed_scale then
        self:change_scale_rate()
    end
end

function no_random:initialize()
    setting:bind_setting("no_random", self.setting)

    routine:hook(self)

    re.on_script_reset(function() self:reset_scale_rate() end)

    ui:cluster("fatal_quest", "任务关键功能")
    ui:checkbox("fatal_quest", "no_random", "fixed_scale", "固定体型：", function() self:toggle_fixed_scale() end)
    ui:sameline("fatal_quest")
    ui:slider_float("fatal_quest", "no_random", "scale", nil, 0.8, 1.25, "%.2f", function()
        if self.setting.fixed_scale then
            self:change_scale_rate()
        end
    end)

    ui:static_text("fatal_quest", "变更出生坐标：")
    ui:sameline("fatal_quest")
    ui:combo("fatal_quest", "no_random", "spawn_position", nil, { 4, 0, 1, 2, 3, }, { "默认", "位置1", "位置2",
        "位置3", "位置4", })

    snow.enemy.EnemyManager.find_boss_init_position:sdk_hook(function(parameters)
        if self.setting.spawn_position < 4 then
            parameters[4] = sdk.to_ptr(self.setting.spawn_position)
        end
        return sdk.CALL_ORIGINAL
    end)

    ui:static_text("fatal_quest", "变更出生区域：")
    ui:sameline("fatal_quest")
    ui:combo("fatal_quest", "no_random", "spawn_area", nil, { 4, 1, 2, 3, }, { "默认", "60%区", "30%区", "10%区", })

    snow.enemy.EnemyBossInitSetData.StageInfo.findSetInfo:sdk_hook(nil, function(result)
        return self:change_spawn_area(result)
    end)
end

function no_random:normalize()
    if status:current_status() ~= status.logical_status.none then
        self:post_before_village()
    end
end

return no_random
